package com.lgl.scsheader.system.controller;

import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.system.model.SysUser;
import com.lgl.scsapi.util.utils.Constants;
import com.lgl.scsapi.util.utils.Tools;
import com.lgl.scsheader.base.controller.BaseController;
import com.lgl.scsheader.system.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/*
 * 登录controller
 */
//@Slf4j
@RestController
@RequestMapping(value = "/login")
public class LoginController extends BaseController {
	private Logger log = LoggerFactory.getLogger(LoginController.class);
	@Resource(name="userService")
	private UserService userService;

	//获取登录验证码
    @RequestMapping(value = "/getCode")
    public void getCode(HttpServletResponse response){
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        String code = drawImg(output);

        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        session.setAttribute(Constants.SESSION_SECURITY_CODE, code);
        try {
            ServletOutputStream out = response.getOutputStream();
            output.writeTo(out);
        } catch (IOException e) {
            log.error("写入图片报错",e);
        }
    }

    /**
     * 画图片
     * @param output
     * @return
     */
    private String drawImg(ByteArrayOutputStream output){
        String code = "";
        for(int i = 0; i < 4; i ++){
            code += Tools.randomChar();
        }
        int width = 70;
        int height = 28;
        BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
        Font font = new Font("Times New Roman",Font.PLAIN,20);
        Graphics2D g = bi.createGraphics();
        g.setFont(font);
        Color color = new Color(66,2,82);
        g.setColor(color);
        g.setBackground(new Color(226,226,240));
        g.clearRect(0, 0, width, height);
        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(code, context);
        double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = bounds.getY();
        double baseY = y - ascent;
        g.drawString(code, (int)x, (int)baseY);
        g.dispose();
        try {
            ImageIO.write(bi, "jpg", output);
        } catch (IOException e) {
            log.error("画图出错",e);
        }
        return code;
    }

	/**
	 * 获取登录用户的IP
	 * @throws Exception 
	 */
	public void getRemortIP(String USERNAME) {
		PageData pd = new PageData();
		HttpServletRequest request = this.getRequest();
		String ip = "";
		if (request.getHeader("x-forwarded-for") == null) {  
			ip = request.getRemoteAddr();  
	    }else{
	    	ip = request.getHeader("x-forwarded-for");  
	    }
		pd.put("USERNAME", USERNAME);
		pd.put("IP", ip);
		userService.saveIP(pd);
	}

	/**
	 * 请求登录，验证用户
	 */
	@PostMapping(value="/goLogin")
	public Object goLogin(HttpServletResponse response){
		PageData pd = this.getPageData();
		String status = "0",checkCode = pd.getString("checkCode"),
        userName = pd.getString("loginName"), password = pd.getString("password");
		//没有验证码
        pd.clear();
		if(!StringUtils.hasText(checkCode) || checkCode.length() != 4){
            pd.clear();
            pd.put("result", "1");
            return pd;
		}
		//没有用户名、密码
        if(!StringUtils.hasText(userName) || !StringUtils.hasText(password)){
            pd.clear();
            pd.put("result", "2");
            return pd;
        }
        //shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        //获取session中的验证码
        String sessionCode = (String)session.getAttribute(Constants.SESSION_SECURITY_CODE);
        //验证码失效
        if(!StringUtils.hasText(sessionCode)){
            pd.clear();
            pd.put("result", "3");
            return pd;
        }
        //验证码错误
        if(!sessionCode.equalsIgnoreCase(checkCode)){
            pd.clear();
            pd.put("result", "4");
            return pd;
        }
        //密码加密
        String hashPassword = new SimpleHash(Constants.ALGORITHM_NAME,password, Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
        pd.put("userName", userName);
        pd.put("password", hashPassword);
		try {
			SysUser sysUser = userService.getUserInfo(pd);
			if(sysUser == null) {
			    pd.clear();
				pd.put("result", "6");
				return pd;
			}
            session.setAttribute(Constants.SESSION_USER, sysUser);
            session.removeAttribute(Constants.SESSION_SECURITY_CODE);
			//shiro加入身份验证
			Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(userName, hashPassword);
			subject.login(token);
		} catch (Exception e) {
			status = "5";
			log.error("shiro登录失败",e);
		}
        pd.clear();
		pd.put("result", status);
		return pd;
	}

	/**
	 * 用户注销
	 */
	@RequestMapping(value="/logout")
	public void logout(HttpServletResponse response){
        try {
		    //shiro管理的session
            Subject currentUser = SecurityUtils.getSubject();
            Session session = currentUser.getSession();
            session.removeAttribute(Constants.SESSION_USER);
            //shiro销毁登录
            currentUser.logout();

            //跳转到登录页面
            response.sendRedirect("/");
        }catch (Exception e){
            log.error("用户退出登录报错", e);
        }
	}

}